import {
	IContext,
	IPanelControllerControllerParams,
	IPanelDetailAbility,
	IParam,
} from '@/core/interface';
import { deepCopy, hasFunction } from '@/core/utils';
import { PanelDetailController } from './panel-detail-controller';

/**
 * 面板容器控制器
 *
 * @export
 * @class PanelContainerController
 * @extends {PanelDetailController}
 */
export class PanelContainerController extends PanelDetailController {
	/**
	 * 子项
	 *
	 * @type {string[]}
	 * @memberof PanelContainerController
	 */
	public details: string[] = [];

	/**
	 * 标题关闭模式
	 *
	 * @type {number}
	 * @memberof PanelContainerController
	 */
	public titleBarCloseMode = 0;

	/**
	 * 数据区域类型
	 * @description 值模式 [数据面板模式] {NONE：无、 LOGINFORM：登录表单、 SINGLEDATA：单项数据、 MULTIDATA：多项数据、 INHERIT：继承、 USER：用户自定义 }
	 * @type {( string | 'NONE' | 'LOGINFORM' | 'SINGLEDATA' | 'MULTIDATA' | 'INHERIT' | 'USER')}
	 * @memberof PanelContainerController
	 */
	public dataRegionType:
		| string
		| 'NONE'
		| 'LOGINFORM'
		| 'SINGLEDATA'
		| 'MULTIDATA'
		| 'INHERIT'
		| 'USER'
		| '' = '';

	/**
	 * 数据源类型
	 * @description 值模式 [数据面板源（全部）] {DEACTION：实体行为、 DEDATASET：实体集合、 DELOGIC：实体逻辑、 APPGLOBALPARAM：绑定应用全局变量、 TOPVIEWSESSIONPARAM：绑定顶级视图会话共享变量、 VIEWSESSIONPARAM：绑定当前视图会话共享变量 }
	 * @type {( string | 'DEACTION' | 'DEDATASET' | 'DELOGIC' | 'APPGLOBALPARAM' | 'TOPVIEWSESSIONPARAM' | 'VIEWSESSIONPARAM')}
	 * @memberof PanelContainerController
	 */
	public dataSourceType:
		| string
		| 'DEACTION'
		| 'DEDATASET'
		| 'DELOGIC'
		| 'APPGLOBALPARAM'
		| 'TOPVIEWSESSIONPARAM'
		| 'VIEWSESSIONPARAM'
		| '' = '';

	/**
	 * 应用实体codeName
	 *
	 * @type {(string | undefined)}
	 * @memberof PanelContainerController
	 */
	public appDataEntityCodeName: string | undefined = undefined;

	/**
	 * 应用实体方法CodeName
	 *
	 * @type {(string | undefined)}
	 * @memberof PanelContainerController
	 */
	public appDEMethodCodeName: string | undefined = undefined;

	/**
	 * 应用实体界面逻辑Tag
	 *
	 * @type {(string | undefined)}
	 * @memberof PanelContainerController
	 */
	public appDELogicTag: string | undefined = undefined;

	/**
	 * 数据变量属性(当数据源类型为'APPGLOBALPARAM' 'TOPVIEWSESSIONPARAM' 'VIEWSESSIONPARAM' 时使用)
	 *
	 * @type {(string | undefined)}
	 * @memberof PanelContainerController
	 */
	public dataName: string | undefined = undefined;

	/**
	 * Creates an instance of PanelContainerController.
	 * @param {*} [opts={}]
	 * @memberof PanelContainerController
	 */
	public constructor(opts: IPanelControllerControllerParams, context: IContext, viewParams: IParam) {
		super(opts, context, viewParams);
		this.details = opts.details;
		this.titleBarCloseMode = opts.titleBarCloseMode;
		this.appDataEntityCodeName = opts.appDataEntityCodeName;
		this.appDEMethodCodeName = opts.appDEMethodCodeName;
		this.appDELogicTag = opts.appDELogicTag;
		this.dataName = opts.dataName;
		this.dataRegionType = opts.dataRegionType;
		this.dataSourceType = opts.dataSourceType;
	}

	/**
	 * 获取容器元素样式(仅限容器元素)
	 *
	 * @return {*}
	 * @memberof PanelContainerController
	 */
	public getElementStyle() {
		const containerStyle = {};
		//边缘布局容器盒子大小由布局组件内部计算
		if (this.layout !== 'BORDER') {
			Object.assign(containerStyle, this.getBoxSizeStyle());
		}
		Object.assign(containerStyle, this.getSpecificStyle());
		Object.assign(containerStyle, this.getStyleCode());
		return containerStyle;
	}

	/**
	 * 获取样式名
	 *
	 * @return {*}  {IParam}
	 * @memberof PanelContainerController
	 */
	public getClassNames(): IParam {
		const classNames = super.getClassNames();
		Object.assign(classNames, this.getFlexClassNames());
		return classNames;
	}

    /**
     * 获取标签动态样式表
     *
     * @protected
     * @return {*} 
     * @memberof PanelContainerController
     */
    protected getLabelDynaClass() {
        const dynaClass = {};
        try {
            const data = this.data;
            const content = this.context;
            const viewParams = this.viewParams;
            if (this.labelDynaClass) {
                Object.assign(dynaClass,...eval(this.labelDynaClass))
            }
        } catch (error) {
            
        }
        return dynaClass;
    }

    /**
	 * 获取Flex布局方向类名（元素）
	 *
	 * @protected
	 * @return {*}
	 * @memberof PanelContainerController
	 */
	protected getFlexClassNames() {
		const boxClassNames = {};
		if (
			this.flexParams.align ||
			this.flexParams.dir ||
			this.flexParams.vAlign
		) {
			Object.assign(boxClassNames, { 'flex-element': true });
			if (this.flexParams.dir) {
				Object.assign(boxClassNames, {
					[`flex-dir--${this.flexParams.dir.toLowerCase()}`]: true,
				});
			}
			if (this.flexParams.align) {
				Object.assign(boxClassNames, {
					[`flex-align--${this.flexParams.align.toLowerCase()}`]: true,
				});
			}
			if (this.flexParams.vAlign) {
				Object.assign(boxClassNames, {
					[`flex-valign--${this.flexParams.vAlign.toLowerCase()}`]: true,
				});
			}
		}
		return boxClassNames;
	}

	/**
	 * 获取容器特有样式（主要包含背景图片）
	 *
	 * @protected
	 * @memberof PanelContainerController
	 */
	protected getSpecificStyle() {
		const boxStyle = {};
		if (
			this.sysImage &&
			(this.sysImage.imagePath || this.sysImage.rawContent)
		) {
			Object.assign(boxStyle, {
				background: `url('${
					this.sysImage.imagePath || this.sysImage.rawContent
				}') no-repeat 0px 0px`,
				'background-size': '100% 100%',
			});
			if (!this.layoutWidth) {
				Object.assign(boxStyle, { width: '100%' });
			}
			if (!this.layoutHeight) {
				Object.assign(boxStyle, { height: '100%' });
			}
		}
		return boxStyle;
	}

	/**
	 * 加载
	 *
	 * @param {*} context
	 * @param {*} viewParams
	 * @memberof PanelContainerController
	 */
	public async load(context: any, viewParams: any) {
		const nullData = {};
		switch (this.dataRegionType) {
			case 'LOGINFORM':
				this.data = nullData;
				break;
			case 'INHERIT':
				if (!this.parentName) {
					if (this.type == 'VIEWLAYOUT') {
						this.data = nullData;
					} else {
						this.data = this.panel.store.data;
					}
				} else {
					let parentItem =
						this.panel.store.layoutModelDetails[
							`${this.parentName}_${this.index}`
						];
					if (!parentItem) {
						parentItem = this.panel.store.layoutModelDetails[this.parentName];
					}
					if (parentItem) {
						if (
							parentItem.dataRegionType === 'MULTIDATA' &&
							parentItem['data'] &&
							parentItem['data'].length > 0
						) {
							this.data = parentItem.getData()[this.getIndex()];
						} else {
							this.data = parentItem.getData();
						}
					}
				}
				break;
			case 'SINGLEDATA':
			case 'MULTIDATA':
				this.data = await this.loadData(context, viewParams);
				break;
			default:
				console.warn(`${this.dataRegionType}数据域未实现`);
				break;
		}
	}

	/**
	 * 加载数据
	 *
	 * @param {*} context
	 * @param {*} viewParams
	 * @return {*}
	 * @memberof PanelContainerController
	 */
	public async loadData(context: IContext, viewParams: IParam) {
		let data = {};
		try {
			if (
				this.dataSourceType === 'DEACTION' ||
				this.dataSourceType === 'DEDATASET'
			) {
				if (this.appDataEntityCodeName && this.appDEMethodCodeName) {
					const service = await App.getDataService(
						this.appDataEntityCodeName,
						context
					);
					if (service) {
						if (
							service[this.appDEMethodCodeName] &&
							service[this.appDEMethodCodeName] instanceof Function
						) {
							const response = await service[this.appDEMethodCodeName](
								context,
								viewParams
							);
							if (response.success) {
								data = response.data;
							}
						}
					}
				}
			} else if (this.dataSourceType === 'DELOGIC') {
				if (this.appDataEntityCodeName) {
					const service = await App.getDataService(
						this.appDataEntityCodeName,
						context
					);
					if (this.appDELogicTag) {
						data = await service.executeUILogic(
							this.appDELogicTag,
							context,
							viewParams,
							[],
							null,
							this.getAbility()
						);
					}
				}
			} else if (this.dataSourceType === 'APPGLOBALPARAM') {
				if (this.dataName) {
					const viewCtx =
						this.panel.store && this.panel.store.viewCtx
							? this.panel.store.viewCtx
							: {};
					data = viewCtx.appGlobal[this.dataName];
				}
			} else if (this.dataSourceType === 'TOPVIEWSESSIONPARAM') {
				if (this.dataName && context.srfsessionid) {
					const viewCtx =
						this.panel.store && this.panel.store.viewCtx
							? this.panel.store.viewCtx
							: {};
					const dataRange =
						viewCtx.routeViewGlobal &&
						viewCtx.routeViewGlobal[context.srfsessionid]
							? viewCtx.routeViewGlobal[context.srfsessionid]
							: {};
					data = dataRange[this.dataName];
				}
			} else if (this.dataSourceType === 'VIEWSESSIONPARAM') {
				if (this.dataName) {
					const viewCtx =
						this.panel.store && this.panel.store.viewCtx
							? this.panel.store.viewCtx
							: {};
					data = viewCtx.viewGlobal[this.dataName];
				}
			} else {
				console.warn(`${this.dataSourceType}数据源类型未实现`);
			}
		} catch (error) {
			console.error(`${this.dataSourceType}数据源请求数据异常`);
		}
		return data;
	}

	/**
	 * 设置数据
	 *
	 * @param {*} args
	 * @memberof PanelContainerController
	 */
	public setData(args: any) {
		const { name, value, index } = args;
		switch (this.dataRegionType) {
			case 'LOGINFORM':
				this.data[name] = value;
				break;
			case 'INHERIT':
				this.data[name] = value;
				if (this.parentName) {
					const parentItem =
						this.panel.store.layoutModelDetails[this.parentName];
					this.data[name] = value;
					if (parentItem) {
						if (
							parentItem.dataRegionType &&
							parentItem.dataRegionType === 'MULTIDATA'
						) {
							// 多数据域第一层子项传整条数据值
							parentItem.setData({ name, value: this.data, index });
						} else {
							parentItem.setData({ name, value, index });
						}
					}
				}
				break;
			case 'SINGLEDATA':
				this.data[name] = value;
				break;
			case 'MULTIDATA':
				this.data[index] = value;
				break;
			default:
				this.data[name] = value;
				break;
		}
	}

	/**
	 * 重置当前项数据
	 *
	 * @memberof PanelContainerController
	 */
	public reSetData() {
		switch (this.dataRegionType) {
			case 'LOGINFORM':
			case 'SINGLEDATA':
				this.data = {};
				break;
			case 'INHERIT':
			case 'USER':
				this.data = {};
				break;
			case 'MULTIDATA':
				this.data = [];
				break;
			default:
				this.data = {};
				break;
		}
	}

	/**
	 * 刷新数据域
	 *
	 * @memberof PanelContainerController
	 */
	public refreshDataArea(viewParams?: IParam) {
        console.warn(`${this.dataRegionType} 数据域未实现`);
	}

	/**
	 * 建立数据
	 *
	 * @param {IContext} context
	 * @param {IParam} viewParams
	 * @param {IParam[]} args
	 * @memberof PanelContainerController
	 */
	public async createData(
		context: IContext,
		viewParams: IParam,
		args: IParam[]
	) {
		if (this.appDataEntityCodeName) {
			const data = args[0];
			const service = await App.getDataService(
				this.appDataEntityCodeName,
				context
			);
			if (service) {
				const key = service.appEntityKeyCodeName.toLowerCase();
				if (data.hasOwnProperty(key)) {
					delete data[key];
				}
				service
					.Create(context, data)
					.then((response: any) => {
						if (!response.success) {
							App.getNotificationHelper().error(
								App.ts(
									'app.error.implementlogicerror',
									'当前环境无法执行建立数据逻辑[执行行为异常]'
								)
							);
							return;
						}
						if (hasFunction(this.panel, 'refresh')) {
							this.panel.refresh();
						}
					})
					.catch((error: any) => {
						App.getNotificationHelper().error(
							App.ts(
								'app.error.implementlogicerror',
								'当前环境无法执行建立数据逻辑[执行行为异常]'
							)
						);
					});
			}
		}
	}

	/**
	 * 删除数据
	 *
	 * @param {IContext} context
	 * @param {IParam} viewParams
	 * @param {IParam[]} args
	 * @memberof PanelContainerController
	 */
	public async removeData(
		context: IContext,
		viewParams: IParam,
		args: IParam[]
	) {
		if (this.appDataEntityCodeName) {
			const data = args[0];
			const service = await App.getDataService(
				this.appDataEntityCodeName,
				context
			);
			if (service) {
				const tempContext = deepCopy(context);
				const key = service.appEntityKeyCodeName.toLowerCase();
				const name = service.appEntityCodeName.toLowerCase();
				if (data.hasOwnProperty(key)) {
					Object.assign(tempContext, { [name]: data[key] });
				}
				service
					.Remove(tempContext, data)
					.then((response: any) => {
						if (!response.success) {
							App.getNotificationHelper().error(
								App.ts(
									'app.error.deletelogicerror',
									'当前环境无法执行删除数据逻辑[执行行为异常]'
								)
							);
							return;
						}
						if (hasFunction(this.panel, 'refresh')) {
							this.panel.refresh();
						}
					})
					.catch((error: any) => {
						App.getNotificationHelper().error(
							App.ts(
								'app.error.deletelogicerror',
								'当前环境无法执行删除数据逻辑[执行行为异常]'
							)
						);
					});
			}
		}
	}

	/**
	 * 保存数据
	 *
	 * @param {IContext} context
	 * @param {IParam} viewParams
	 * @param {IParam[]} args
	 * @memberof PanelContainerController
	 */
	public async saveData(context: IContext, viewParams: IParam, args: IParam[]) {
		if (
			Object.is(this.viewType, 'DEPICKUPVIEW') ||
			Object.is(this.viewType, 'DEMPICKUPVIEW')
		) {
			if (this.panel.confirm && this.panel.confirm instanceof Function) {
				this.panel.confirm();
			}
		} else {
			if (this.appDataEntityCodeName) {
				const data = args[0];
				const service = await App.getDataService(
					this.appDataEntityCodeName,
					context
				);
				if (service) {
					let action = '';
					const tempContext = deepCopy(context);
					const key = service.appEntityKeyCodeName.toLowerCase();
					const name = service.appEntityCodeName.toLowerCase();
					if (data.hasOwnProperty(key)) {
						Object.assign(tempContext, { [name]: data[key] });
						action = 'Update';
					} else {
						action = 'Create';
					}
					if (service[action] && service[action] instanceof Function) {
						service[action](tempContext, data)
							.then((response: any) => {
								if (!response.success) {
									App.getNotificationHelper().error(
										App.ts(
											'app.error.implementlogicerror',
											'当前环境无法执行建立数据逻辑[执行行为异常]'
										)
									);
									return;
								}
							})
							.catch((error: any) => {
								App.getNotificationHelper().error(
									App.ts(
										'app.error.implementlogicerror',
										'当前环境无法执行建立数据逻辑[执行行为异常]'
									)
								);
							});
					}
				}
			}
		}
	}

	/**
	 * 获取能力
	 *
	 * @return {*}  {IPanelDetailAbility}
	 * @memberof PanelContainerController
	 */
	public getAbility(): IPanelDetailAbility {
		return {
			...super.getAbility(),
			refreshDataArea: this.refreshDataArea.bind(this),
			createData: this.createData.bind(this),
			removeData: this.removeData.bind(this),
			saveData: this.saveData.bind(this),
		};
	}
}
